home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / eat.c < prev    next >
C/C++ Source or Header  |  1993-01-18  |  47KB  |  1,868 lines

  1. /*    SCCS Id: @(#)eat.c    3.1    92/12/06    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include    "hack.h"
  6. /*#define DEBUG        /* uncomment to enable new eat code debugging */
  7.  
  8. #ifdef DEBUG
  9. # ifdef WIZARD
  10. #define debugpline    if (wizard) pline
  11. # else
  12. #define debugpline    pline
  13. # endif
  14. #endif
  15.  
  16. STATIC_PTR int NDECL(eatmdone);
  17. STATIC_PTR int NDECL(eatfood);
  18. STATIC_PTR int NDECL(opentin);
  19. STATIC_PTR int NDECL(unfaint);
  20.  
  21. #ifdef OVLB
  22. static void FDECL(choke, (struct obj *));
  23. static void NDECL(recalc_wt);
  24. static struct obj *FDECL(touchfood, (struct obj *));
  25. static void NDECL(do_reset_eat);
  26. static void FDECL(done_eating, (BOOLEAN_P));
  27. static void FDECL(cprefx, (int));
  28. static int FDECL(intrinsic_possible, (int,struct permonst *));
  29. static void FDECL(givit, (int,struct permonst *));
  30. static void FDECL(cpostfx, (int));
  31. static void FDECL(start_tin, (struct obj *));
  32. static int FDECL(eatcorpse, (struct obj *));
  33. static void FDECL(start_eating, (struct obj *));
  34. static void FDECL(fprefx, (struct obj *));
  35. static void FDECL(fpostfx, (struct obj *));
  36. static int NDECL(bite);
  37.  
  38. #ifdef POLYSELF
  39. static int FDECL(rottenfood, (struct obj *));
  40. static void NDECL(eatspecial);
  41. static void FDECL(eatring, (struct obj *));
  42. static const char * FDECL(foodword, (struct obj *));
  43. #else
  44. static int NDECL(rottenfood);
  45. #endif /* POLYSELF */
  46.  
  47. char corpsename[60];
  48. char msgbuf[BUFSZ];
  49.  
  50. #endif /* OVLB */
  51.  
  52. /* hunger texts used on bottom line (each 8 chars long) */
  53. #define SATIATED    0
  54. #define NOT_HUNGRY    1
  55. #define HUNGRY        2
  56. #define WEAK        3
  57. #define FAINTING    4
  58. #define FAINTED        5
  59. #define STARVED        6
  60.  
  61. #ifdef OVLB
  62.  
  63. const char *hu_stat[] = {
  64.     "Satiated",
  65.     "        ",
  66.     "Hungry  ",
  67.     "Weak    ",
  68.     "Fainting",
  69.     "Fainted ",
  70.     "Starved "
  71. };
  72.  
  73. #endif /* OVLB */
  74.  
  75. #ifndef OVLB
  76.  
  77. STATIC_DCL const char NEARDATA comestibles[];
  78. #ifdef POLYSELF
  79. STATIC_OVL const char NEARDATA allobj[];
  80. #endif /* POLYSELF */
  81.  
  82. #else
  83.  
  84. STATIC_OVL const char NEARDATA comestibles[] = { FOOD_CLASS, 0 };
  85.  
  86. #ifdef POLYSELF
  87. /* Gold must come first for getobj(). */
  88. STATIC_OVL const char NEARDATA allobj[] = {
  89.     GOLD_CLASS, WEAPON_CLASS, ARMOR_CLASS, POTION_CLASS, SCROLL_CLASS,
  90.     WAND_CLASS, RING_CLASS, AMULET_CLASS, FOOD_CLASS, TOOL_CLASS,
  91.     GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, SPBOOK_CLASS, 0 };
  92. #endif /* POLYSELF */
  93.  
  94. #endif /* OVLB */
  95. #ifdef OVL1
  96. # ifdef POLYSELF
  97.  
  98. boolean
  99. is_edible(obj)
  100. register struct obj *obj;
  101. {
  102.     if (metallivorous(uasmon) && is_metallic(obj))
  103.         return TRUE;
  104.     if (u.umonnum == PM_GELATINOUS_CUBE && is_organic(obj))
  105.         return TRUE;
  106.     return !!index(comestibles, obj->oclass);
  107. }
  108. # endif /* POLYSELF */
  109. #endif /* OVL1 */
  110. #ifdef OVLB
  111.  
  112. void
  113. init_uhunger(){
  114.     u.uhunger = 900;
  115.     u.uhs = NOT_HUNGRY;
  116. }
  117.  
  118. static const struct { const char *txt; int nut; } tintxts[] = {
  119.     {"deep fried",     60},
  120.     {"pickled",     40},
  121.     {"soup made from", 20},
  122.     {"pureed",    500},
  123.     {"rotten",    -50},
  124.     {"homemade",     50},
  125.     {"", 0}
  126. };
  127. #define    TTSZ    SIZE(tintxts)
  128.  
  129. static struct {
  130.     struct    obj *tin;
  131.     int    usedtime, reqtime;
  132. } NEARDATA tin;
  133.  
  134. static struct {
  135.     struct    obj *piece;    /* the thing being eaten, or last thing that
  136.                  * was partially eaten, unless that thing was
  137.                  * a tin, which uses the tin structure above */
  138.     int    usedtime,    /* turns spent eating */
  139.         reqtime;    /* turns required to eat */
  140.     int    nmod;        /* coded nutrition per turn */
  141.     Bitfield(canchoke,1);    /* was satiated at beginning */
  142.     Bitfield(fullwarn,1);    /* have warned about being full */
  143.     Bitfield(eating,1);    /* victual currently being eaten */
  144.     Bitfield(doreset,1);    /* stop eating at end of turn */
  145. } NEARDATA victual;
  146.  
  147. STATIC_PTR
  148. int
  149. eatmdone() {        /* called after mimicing is over */
  150.     u.usym =
  151. #ifdef POLYSELF
  152.         u.mtimedone ? uasmon->mlet :
  153. #endif
  154.         S_HUMAN;
  155.     newsym(u.ux,u.uy);
  156.     return 0;
  157. }
  158.  
  159. /* Created by GAN 01/28/87
  160.  * Amended by AKP 09/22/87: if not hard, don't choke, just vomit.
  161.  * Amended by 3.  06/12/89: if not hard, sometimes choke anyway, to keep risk.
  162.  *          11/10/89: if hard, rarely vomit anyway, for slim chance.
  163.  */
  164. /*ARGSUSED*/
  165. static void
  166. choke(food)    /* To a full belly all food is bad. (It.) */
  167.     register struct obj *food;
  168. {
  169.     /* only happens if you were satiated */
  170.     if(u.uhs != SATIATED) return;
  171.  
  172.     if (pl_character[0] == 'K' && u.ualign.type == A_LAWFUL)
  173.         u.ualign.record--;    /* gluttony is unchivalrous */
  174.  
  175.     if (!rn2(20)) {
  176.         You("stuff yourself and then vomit voluminously.");
  177.         morehungry(1000);    /* you just got *very* sick! */
  178.         vomit();
  179.     } else {
  180.         killer_format = KILLED_BY_AN;
  181.         /*
  182.          * Note all "killer"s below read "Choked on %s" on the
  183.          * high score list & tombstone.  So plan accordingly.
  184.          */
  185.         if(food) {
  186. #ifdef POLYSELF
  187.             You("choke over your %s.", foodword(food));
  188.             if (food->oclass == GOLD_CLASS) {
  189.                 killer_format = KILLED_BY;
  190.                 killer = "eating too rich a meal";
  191.             } else {
  192. #else
  193.                 You("choke over your food.");
  194. #endif
  195.                 killer = singular(food, xname);
  196. #ifdef POLYSELF
  197.             }
  198. #endif
  199.         } else {
  200.             You("choke over it.");
  201.             killer = "quick snack";
  202.         }
  203.         You("die...");
  204.         done(CHOKING);
  205.     }
  206. }
  207.  
  208. static void
  209. recalc_wt() {    /* modify object wt. depending on time spent consuming it */
  210.     register struct obj *piece = victual.piece;
  211.  
  212. #ifdef DEBUG
  213.     debugpline("Old weight = %d", piece->owt);
  214.     debugpline("Used time = %d, Req'd time = %d",
  215.         victual.usedtime, victual.reqtime);
  216. #endif
  217.     /* weight(piece) = weight of full item */
  218.     if(victual.usedtime)
  219.         piece->owt = eaten_stat(weight(piece), piece);
  220. #ifdef DEBUG
  221.     debugpline("New weight = %d", piece->owt);
  222. #endif
  223. }
  224.  
  225. void
  226. reset_eat() {        /* called when eating interrupted by an event */
  227.  
  228.     /* we only set a flag here - the actual reset process is done after
  229.      * the round is spent eating.
  230.      */
  231.     if(victual.eating && !victual.doreset) {
  232. #ifdef DEBUG
  233.         debugpline("reset_eat...");
  234. #endif
  235.         victual.doreset = TRUE;
  236.     }
  237.     return;
  238. }
  239.  
  240. void
  241. bill_dummy_object(otmp)
  242. register struct obj *otmp;
  243. {
  244.     /* Create a dummy duplicate to put on bill.  The duplicate exists
  245.      * only in the billobjs chain.  This function is used when a store
  246.      * object is being altered, and a copy of the original is needed
  247.      * for billing purposes.
  248.      */
  249.     register struct obj *dummy;
  250.  
  251.     if(otmp->unpaid)
  252.         subfrombill(otmp, shop_keeper(*u.ushops));
  253.     dummy = newobj(otmp->onamelth);
  254.     *dummy = *otmp;
  255.     dummy->o_id = flags.ident++;
  256.     dummy->owt = weight(dummy);
  257.     if(otmp->onamelth)
  258.         (void)strncpy(ONAME(dummy),ONAME(otmp), (int)otmp->onamelth);
  259.     if(Is_candle(dummy)) dummy->lamplit = 0;
  260.     addtobill(dummy, FALSE, TRUE, TRUE);
  261. }
  262.  
  263. static struct obj *
  264. touchfood(otmp)
  265. register struct obj *otmp;
  266. {
  267.     if (otmp->quan > 1L) {
  268.         if(!carried(otmp))
  269.         (void) splitobj(otmp, 1L);
  270.         else
  271.         otmp = splitobj(otmp, otmp->quan - 1L);
  272. #ifdef DEBUG
  273.         debugpline("split object,");
  274. #endif
  275.     }
  276.  
  277.     if (!otmp->oeaten) {
  278.         if(((!carried(otmp) && costly_spot(otmp->ox, otmp->oy) &&
  279.          saleable(rooms[*u.ushops-ROOMOFFSET].rtype-SHOPBASE, otmp))
  280.          || otmp->unpaid) &&
  281.          (otmp->otyp == CORPSE || objects[otmp->otyp].oc_delay > 1)) {
  282.         /* create a dummy duplicate to put on bill */
  283.         You("bite it, you bought it!");
  284.         bill_dummy_object(otmp);
  285.         }
  286.         otmp->oeaten = (otmp->otyp == CORPSE ?
  287.                 (int)mons[otmp->corpsenm].cnutrit :
  288.                 objects[otmp->otyp].oc_nutrition);
  289.     }
  290.  
  291.     if (carried(otmp)) {
  292.         freeinv(otmp);
  293.         if(inv_cnt() >= 52)
  294.         dropy(otmp);
  295.         else
  296.         otmp = addinv(otmp); /* unlikely but a merge is possible */
  297.     }
  298.     return(otmp);
  299. }
  300.  
  301. /* When food decays, in the middle of your meal, we don't want to dereference
  302.  * any dangling pointers, so set it to null (which should still trigger
  303.  * do_reset_eat() at the beginning of eatfood()) and check for null pointers
  304.  * in do_reset_eat().
  305.  */
  306. void
  307. food_disappears(obj)
  308. register struct obj *obj;
  309. {
  310.     if (obj == victual.piece) victual.piece = (struct obj *)0;
  311. }
  312.  
  313. static void
  314. do_reset_eat() {
  315.  
  316. #ifdef DEBUG
  317.     debugpline("do_reset_eat...");
  318. #endif
  319.     if (victual.piece) {
  320.         victual.piece = touchfood(victual.piece);
  321.         recalc_wt();
  322.     }
  323.     victual.fullwarn = victual.eating = victual.doreset = FALSE;
  324.     /* Do not set canchoke to FALSE; if we continue eating the same object
  325.      * we need to know if canchoke was set when they started eating it the
  326.      * previous time.  And if we don't continue eating the same object
  327.      * canchoke always gets recalculated anyway.
  328.      */
  329.     stop_occupation();
  330. }
  331.  
  332. STATIC_PTR
  333. int
  334. eatfood() {        /* called each move during eating process */
  335.     if(!carried(victual.piece) && !obj_here(victual.piece, u.ux, u.uy)) {
  336.         /* maybe it was stolen? */
  337.         do_reset_eat();
  338.         return(0);
  339.     }
  340.     if(!victual.eating) return(0);
  341.  
  342.     if(++victual.usedtime < victual.reqtime) {
  343.         if(bite()) return(0);
  344.         return(1);    /* still busy */
  345.     } else {    /* done */
  346.         done_eating(TRUE);
  347.         return(0);
  348.     }
  349. }
  350.  
  351. static void
  352. done_eating(message)
  353. boolean message;
  354. {
  355. #ifndef NO_SIGNAL
  356.     victual.piece->in_use = TRUE;
  357. #endif
  358.     if (nomovemsg) {
  359.         if (message) pline(nomovemsg);
  360.         nomovemsg = 0;
  361.     } else if (message)
  362.         You("finish eating %s.", the(singular(victual.piece, xname)));
  363.  
  364.     if(victual.piece->otyp == CORPSE)
  365.         cpostfx(victual.piece->corpsenm);
  366.     else
  367.         fpostfx(victual.piece);
  368.  
  369.     if (carried(victual.piece)) useup(victual.piece);
  370.     else useupf(victual.piece);
  371.     victual.piece = (struct obj *) 0;
  372.     victual.fullwarn = victual.eating = victual.doreset = FALSE;
  373. }
  374.  
  375. static void
  376. cprefx(pm)
  377. register int pm;
  378. {
  379.     if ((pl_character[0]=='E') ? is_elf(&mons[pm]) : is_human(&mons[pm])) {
  380.         You("cannibal!  You will regret this!");
  381.         Aggravate_monster |= FROMOUTSIDE;
  382.     }
  383.  
  384.     switch(pm) {
  385.         case PM_LITTLE_DOG:
  386.         case PM_DOG:
  387.         case PM_LARGE_DOG:
  388.         case PM_KITTEN:
  389.         case PM_HOUSECAT:
  390.         case PM_LARGE_CAT:
  391.         You("feel that eating the %s was a bad idea.", mons[pm].mname);
  392.         Aggravate_monster |= FROMOUTSIDE;
  393.         break;
  394.         case PM_COCKATRICE:
  395.         case PM_MEDUSA:
  396. #ifdef POLYSELF
  397.         if(!resists_ston(uasmon))
  398.             if(!(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)))
  399. #endif
  400.             {
  401.             char *cruft;    /* killer is const char * */
  402.             killer_format = KILLED_BY;
  403.             killer = cruft = (char *)  /* sizeof "s" includes \0 */
  404.                     alloc((unsigned) strlen(mons[pm].mname)
  405.                         + sizeof " meat");
  406.             Sprintf(cruft, "%s meat", mons[pm].mname);
  407.             You("turn to stone.");
  408.             done(STONING);
  409.             }
  410.             break;
  411.         case PM_LIZARD:
  412.         /* Relief from cockatrices -dgk */
  413.         if (Stoned) {
  414.             Stoned = 0;
  415.             You("feel limber!");
  416.         }
  417.         break;
  418.         case PM_DEATH:
  419.         case PM_PESTILENCE:
  420.         case PM_FAMINE:
  421.         { char buf[BUFSZ];
  422.             pline("Eating that is instantly fatal.");
  423.             Sprintf(buf, "unwisely ate the body of %s",
  424.                 mons[pm].mname);
  425.             killer = buf;
  426.             killer_format = NO_KILLER_PREFIX;
  427.             done(DIED);
  428.             /* It so happens that since we know these monsters */
  429.             /* cannot appear in tins, victual.piece will always */
  430.             /* be what we want, which is not generally true. */
  431.             revive_corpse(victual.piece, 0, FALSE);
  432.             return;
  433.         }
  434.         default:
  435.         if(acidic(&mons[pm]) && Stoned) {
  436.             pline("What a pity - you just destroyed a future piece of art!");
  437.             Stoned = 0;
  438.         }
  439.     }
  440.     return;
  441. }
  442.  
  443.  
  444. /*
  445.  * If you add an intrinsic that can be gotten by eating a monster, add it
  446.  * to intrinsic_possible() and givit().  (It must already be in prop.h to
  447.  * be an intrinsic property.)
  448.  * It would be very easy to make the intrinsics not try to give you one
  449.  * that you already had by checking to see if you have it in
  450.  * intrinsic_possible() instead of givit().
  451.  */
  452.  
  453. /* intrinsic_possible() returns TRUE iff a monster can give an intrinsic. */
  454. static int
  455. intrinsic_possible(type, ptr)
  456. int type;
  457. register struct permonst *ptr;
  458. {
  459.     switch (type) {
  460.         case FIRE_RES:
  461. #ifdef DEBUG
  462.         if (ptr->mconveys & MR_FIRE) {
  463.             debugpline("can get fire resistance");
  464.             return(TRUE);
  465.         } else  return(FALSE);
  466. #else
  467.         return(ptr->mconveys & MR_FIRE);
  468. #endif
  469.         case SLEEP_RES:
  470. #ifdef DEBUG
  471.         if (ptr->mconveys & MR_SLEEP) {
  472.             debugpline("can get sleep resistance");
  473.             return(TRUE);
  474.         } else  return(FALSE);
  475. #else
  476.         return(ptr->mconveys & MR_SLEEP);
  477. #endif
  478.         case COLD_RES:
  479. #ifdef DEBUG
  480.         if (ptr->mconveys & MR_COLD) {
  481.             debugpline("can get cold resistance");
  482.             return(TRUE);
  483.         } else  return(FALSE);
  484. #else
  485.         return(ptr->mconveys & MR_COLD);
  486. #endif
  487.         case DISINT_RES:
  488. #ifdef DEBUG
  489.         if (ptr->mconveys & MR_DISINT) {
  490.             debugpline("can get disintegration resistance");
  491.             return(TRUE);
  492.         } else  return(FALSE);
  493. #else
  494.         return(ptr->mconveys & MR_DISINT);
  495. #endif
  496.         case SHOCK_RES:    /* shock (electricity) resistance */
  497. #ifdef DEBUG
  498.         if (ptr->mconveys & MR_ELEC) {
  499.             debugpline("can get shock resistance");
  500.             return(TRUE);
  501.         } else  return(FALSE);
  502. #else
  503.         return(ptr->mconveys & MR_ELEC);
  504. #endif
  505.         case POISON_RES:
  506. #ifdef DEBUG
  507.         if (ptr->mconveys & MR_POISON) {
  508.             debugpline("can get poison resistance");
  509.             return(TRUE);
  510.         } else  return(FALSE);
  511. #else
  512.         return(ptr->mconveys & MR_POISON);
  513. #endif
  514.         case TELEPORT:
  515. #ifdef DEBUG
  516.         if (can_teleport(ptr)) {
  517.             debugpline("can get teleport");
  518.             return(TRUE);
  519.         } else  return(FALSE);
  520. #else
  521.         return(can_teleport(ptr));
  522. #endif
  523.         case TELEPORT_CONTROL:
  524. #ifdef DEBUG
  525.         if (control_teleport(ptr)) {
  526.             debugpline("can get teleport control");
  527.             return(TRUE);
  528.         } else  return(FALSE);
  529. #else
  530.         return(control_teleport(ptr));
  531. #endif
  532.         case TELEPAT:
  533. #ifdef DEBUG
  534.         if (telepathic(ptr)) {
  535.             debugpline("can get telepathy");
  536.             return(TRUE);
  537.         } else  return(FALSE);
  538. #else
  539.         return(telepathic(ptr));
  540. #endif
  541.         default:
  542.         return(FALSE);
  543.     }
  544.     /*NOTREACHED*/
  545. }
  546.  
  547. /* givit() tries to give you an intrinsic based on the monster's level
  548.  * and what type of intrinsic it is trying to give you.
  549.  */
  550. static void
  551. givit(type, ptr)
  552. int type;
  553. register struct permonst *ptr;
  554. {
  555.     register int chance;
  556.  
  557. #ifdef DEBUG
  558.     debugpline("Attempting to give intrinsic %d", type);
  559. #endif
  560.     /* some intrinsics are easier to get than others */
  561.     switch (type) {
  562.         case POISON_RES:
  563.             if ((ptr == &mons[PM_KILLER_BEE] ||
  564.                     ptr == &mons[PM_SCORPION]) && !rn2(4))
  565.                 chance = 1;
  566.             else
  567.                 chance = 15;
  568.             break;
  569.         case TELEPORT:
  570.             chance = 10;
  571.             break;
  572.         case TELEPORT_CONTROL:
  573.             chance = 12;
  574.             break;
  575.         case TELEPAT:
  576.             chance = 1;
  577.             break;
  578.         default:
  579.             chance = 15;
  580.             break;
  581.     }
  582.  
  583.     if (ptr->mlevel <= rn2(chance))
  584.         return;        /* failed die roll */
  585.  
  586.     switch (type) {
  587.         case FIRE_RES:
  588. #ifdef DEBUG
  589.         debugpline("Trying to give fire resistance");
  590. #endif
  591.         if(!(HFire_resistance & FROMOUTSIDE)) {
  592.             You("feel a momentary chill.");
  593.             HFire_resistance |= FROMOUTSIDE;
  594.         }
  595.         break;
  596.         case SLEEP_RES:
  597. #ifdef DEBUG
  598.         debugpline("Trying to give sleep resistance");
  599. #endif
  600.         if(!(HSleep_resistance & FROMOUTSIDE)) {
  601.             You("feel wide awake.");
  602.             HSleep_resistance |= FROMOUTSIDE;
  603.         }
  604.         break;
  605.         case COLD_RES:
  606. #ifdef DEBUG
  607.         debugpline("Trying to give cold resistance");
  608. #endif
  609.         if(!(HCold_resistance & FROMOUTSIDE)) {
  610.             You("feel full of hot air.");
  611.             HCold_resistance |= FROMOUTSIDE;
  612.         }
  613.         break;
  614.         case DISINT_RES:
  615. #ifdef DEBUG
  616.         debugpline("Trying to give disintegration resistance");
  617. #endif
  618.         if(!(HDisint_resistance & FROMOUTSIDE)) {
  619.             You("feel very firm.");
  620.             HDisint_resistance |= FROMOUTSIDE;
  621.         }
  622.         break;
  623.         case SHOCK_RES:    /* shock (electricity) resistance */
  624. #ifdef DEBUG
  625.         debugpline("Trying to give shock resistance");
  626. #endif
  627.         if(!(HShock_resistance & FROMOUTSIDE)) {
  628.             Your("health currently feels amplified!");
  629.             HShock_resistance |= FROMOUTSIDE;
  630.         }
  631.         break;
  632.         case POISON_RES:
  633. #ifdef DEBUG
  634.         debugpline("Trying to give poison resistance");
  635. #endif
  636.         if(!(HPoison_resistance & FROMOUTSIDE)) {
  637.             You("feel healthy.");
  638.             HPoison_resistance |= FROMOUTSIDE;
  639.         }
  640.         break;
  641.         case TELEPORT:
  642. #ifdef DEBUG
  643.         debugpline("Trying to give teleport");
  644. #endif
  645.         if(!(HTeleportation & FROMOUTSIDE)) {
  646.             You("feel very jumpy.");
  647.             HTeleportation |= FROMOUTSIDE;
  648.         }
  649.         break;
  650.         case TELEPORT_CONTROL:
  651. #ifdef DEBUG
  652.         debugpline("Trying to give teleport control");
  653. #endif
  654.         if(!(HTeleport_control & FROMOUTSIDE)) {
  655.             You("feel in control of yourself.");
  656.             HTeleport_control |= FROMOUTSIDE;
  657.         }
  658.         break;
  659.         case TELEPAT:
  660. #ifdef DEBUG
  661.         debugpline("Trying to give telepathy");
  662. #endif
  663.         if(!(HTelepat & FROMOUTSIDE)) {
  664.             You("feel a %s mental acuity.",
  665.                 Hallucination ? "normal" : "strange");
  666.             HTelepat |= FROMOUTSIDE;
  667.             /* If blind, make sure monsters show up. */
  668.             if (Blind) see_monsters();
  669.         }
  670.         break;
  671.         default:
  672. #ifdef DEBUG
  673.         debugpline("Tried to give an impossible intrinsic");
  674. #endif
  675.         break;
  676.     }
  677. }
  678.  
  679. static void
  680. cpostfx(pm)        /* called after completely consuming a corpse */
  681. register int pm;
  682. {
  683.     register int tmp = 0;
  684.  
  685.     switch(pm) {
  686.         case PM_WRAITH:
  687.         pluslvl();
  688.         break;
  689. #ifdef POLYSELF
  690.         case PM_HUMAN_WERERAT:
  691.         u.ulycn = PM_WERERAT;
  692.         break;
  693.         case PM_HUMAN_WEREJACKAL:
  694.         u.ulycn = PM_WEREJACKAL;
  695.         break;
  696.         case PM_HUMAN_WEREWOLF:
  697.         u.ulycn = PM_WEREWOLF;
  698.         break;
  699. #endif
  700.         case PM_NURSE:
  701.         u.uhp = u.uhpmax;
  702.         flags.botl = 1;
  703.         break;
  704.         case PM_STALKER:
  705.         if(!Invis) {
  706.             HInvis = rn1(100, 50);
  707.             if(!See_invisible)
  708.                 newsym(u.ux, u.uy);
  709.         } else {
  710.             register long oldprop = See_invisible;
  711.             if (!(HInvis & INTRINSIC)) You("feel hidden!");
  712.             HInvis |= FROMOUTSIDE;
  713.             HSee_invisible |= FROMOUTSIDE;
  714.             if (!oldprop)
  715.                 newsym(u.ux, u.uy);
  716.         }
  717.         /* fall into next case */
  718.         case PM_YELLOW_LIGHT:
  719.         /* fall into next case */
  720.         case PM_GIANT_BAT:
  721.         make_stunned(HStun + 30,FALSE);
  722.         /* fall into next case */
  723.         case PM_BAT:
  724.         make_stunned(HStun + 30,FALSE);
  725.         break;
  726.         case PM_GIANT_MIMIC:
  727.         tmp += 10;
  728.         /* fall into next case */
  729.         case PM_LARGE_MIMIC:
  730.         tmp += 20;
  731.         /* fall into next case */
  732.         case PM_SMALL_MIMIC:
  733.         tmp += 20;
  734.         if(u.usym == S_HUMAN) {
  735.             You("cannot resist the temptation to mimic a pile of gold.");
  736.             nomul(-tmp);
  737.             afternmv = eatmdone;
  738.             if (pl_character[0]=='E')
  739.             nomovemsg = "You now again prefer mimicking an elf.";
  740.             else
  741.             nomovemsg = "You now again prefer mimicking a human.";
  742.             u.usym = 0; /* hack! no monster sym 0; use for gold */
  743.             newsym(u.ux,u.uy);
  744.         }
  745.         break;
  746.         case PM_QUANTUM_MECHANIC:
  747.         Your("velocity suddenly seems very uncertain!");
  748.         if (Fast & INTRINSIC) {
  749.             Fast &= ~INTRINSIC;
  750.             You("seem slower.");
  751.         } else {
  752.             Fast |= FROMOUTSIDE;
  753.             You("seem faster.");
  754.         }
  755.         break;
  756.         case PM_LIZARD:
  757.         if (HStun > 2)  make_stunned(2L,FALSE);
  758.         if (HConfusion > 2)  make_confused(2L,FALSE);
  759.         break;
  760.         case PM_CHAMELEON:
  761.         You("feel a change coming over you.");
  762. #ifdef POLYSELF
  763.         polyself();
  764. #else
  765.         newman();
  766. #endif
  767.         break;
  768.         case PM_MIND_FLAYER:
  769.         if (ABASE(A_INT) < ATTRMAX(A_INT)) {
  770.             if (!rn2(2)) {
  771.                 pline("Yum! That was real brain food!");
  772.                 (void) adjattrib(A_INT, 1, FALSE);
  773.                 break;    /* don't give them telepathy, too */
  774.             }
  775.         }
  776.         else {
  777.             pline("For some reason, that tasted bland.");
  778.         }
  779.         /* fall through to default case */
  780.         default: {
  781.         register struct permonst *ptr = &mons[pm];
  782.         int i, count;
  783.  
  784.         if(dmgtype(ptr, AD_STUN) || pm==PM_VIOLET_FUNGUS) {
  785.             pline ("Oh wow!  Great stuff!");
  786.             make_hallucinated(HHallucination + 200,FALSE,0L);
  787.         }
  788.         /* prevent polymorph abuse by killing/eating your offspring */
  789.         if(pm >= PM_BABY_GRAY_DRAGON && pm <= PM_BABY_YELLOW_DRAGON)
  790.             return;
  791.         if(is_giant(ptr)) gainstr((struct obj *)0, 0);
  792.  
  793.         /* Check the monster for all of the intrinsics.  If this
  794.          * monster can give more than one, pick one to try to give
  795.          * from among all it can give.
  796.          *
  797.          * If a monster can give 4 intrinsics then you have
  798.          * a 1/1 * 1/2 * 2/3 * 3/4 = 1/4 chance of getting the first,
  799.          * a 1/2 * 2/3 * 3/4 = 1/4 chance of getting the second,
  800.          * a 1/3 * 3/4 = 1/4 chance of getting the third,
  801.          * and a 1/4 chance of getting the fourth.
  802.          *
  803.          * And now a proof by induction:
  804.          * it works for 1 intrinsic (1 in 1 of getting it)
  805.          * for 2 you have a 1 in 2 chance of getting the second,
  806.          *    otherwise you keep the first
  807.          * for 3 you have a 1 in 3 chance of getting the third,
  808.          *    otherwise you keep the first or the second
  809.          * for n+1 you have a 1 in n+1 chance of getting the (n+1)st,
  810.          *    otherwise you keep the previous one.
  811.          * Elliott Kleinrock, October 5, 1990
  812.          */
  813.  
  814.          count = 0;    /* number of possible intrinsics */
  815.          tmp = 0;    /* which one we will try to give */
  816.          for (i = 1; i <= LAST_PROP; i++) {
  817.             if (intrinsic_possible(i, ptr)) {
  818.                 count++;
  819.                 /* a 1 in count chance of replacing the old
  820.                  * one with this one, and a count-1 in count
  821.                  * chance of keeping the old one.  (note
  822.                  * that 1 in 1 and 0 in 1 are what we want
  823.                  * for the first one
  824.                  */
  825.                 if (!rn2(count)) {
  826. #ifdef DEBUG
  827.                     debugpline("Intrinsic %d replacing %d",
  828.                                 i, tmp);
  829. #endif
  830.                     tmp = i;
  831.                 }
  832.             }
  833.          }
  834.  
  835.          /* if any found try to give them one */
  836.          if (count) givit(tmp, ptr);
  837.         }
  838.         break;
  839.     }
  840.     return;
  841. }
  842.  
  843. STATIC_PTR
  844. int
  845. opentin()        /* called during each move whilst opening a tin */
  846. {
  847.     register int r;
  848.  
  849.     if(!carried(tin.tin) && !obj_here(tin.tin, u.ux, u.uy))
  850.                     /* perhaps it was stolen? */
  851.         return(0);        /* %% probably we should use tinoid */
  852.     if(tin.usedtime++ >= 50) {
  853.         You("give up your attempt to open the tin.");
  854.         return(0);
  855.     }
  856.     if(tin.usedtime < tin.reqtime)
  857.         return(1);        /* still busy */
  858.     if(tin.tin->cursed && tin.tin->spe != -1 && !rn2(8)) {
  859.         b_trapped("tin");
  860.         goto use_me;
  861.     }
  862.     You("succeed in opening the tin.");
  863.     if(tin.tin->spe != 1) {
  864.         if(tin.tin->corpsenm == -1) {
  865.         pline("It turns out to be empty.");
  866.         tin.tin->dknown = tin.tin->known = TRUE;
  867.         goto use_me;
  868.         }
  869.         r = tin.tin->cursed ? 4 :        /* Always rotten if cursed */
  870.             (tin.tin->spe == -1) ? 5 :    /* "homemade" if player made */
  871.             rn2(TTSZ-1);        /* else take your pick */
  872.         pline("It smells like %s.", makeplural(
  873.           Hallucination ? rndmonnam() : mons[tin.tin->corpsenm].mname));
  874.         if (yn("Eat it?") == 'n') {
  875.         if (!Hallucination) tin.tin->dknown = tin.tin->known = TRUE;
  876.         if (flags.verbose) You("discard the open tin.");
  877.         goto use_me;
  878.         }
  879.         You("consume %s %s.", tintxts[r].txt,
  880.             mons[tin.tin->corpsenm].mname);
  881.         tin.tin->dknown = tin.tin->known = TRUE;
  882.         cprefx(tin.tin->corpsenm); cpostfx(tin.tin->corpsenm);
  883.  
  884.         /* check for vomiting added by GAN 01/16/87 */
  885.         if(tintxts[r].nut < 0) make_vomiting((long)rn1(15,10), FALSE);
  886.         else lesshungry(tintxts[r].nut);
  887.  
  888.         if(r == 0) {            /* Deep Fried */
  889.         Glib = rnd(15);
  890.         pline("Eating deep fried food made your %s very slippery.",
  891.             makeplural(body_part(FINGER)));
  892.         }
  893.     } else {
  894.         if (tin.tin->cursed)
  895.         pline("It contains some decaying %s substance.",
  896.             Hallucination ? hcolor() : green);
  897.         else
  898.         pline("It contains spinach.");
  899.  
  900.         if (yn("Eat it?") == 'n') {
  901.         if (!Hallucination && !tin.tin->cursed)
  902.             tin.tin->dknown = tin.tin->known = TRUE;
  903.         if (flags.verbose)
  904.             You("discard the open tin.");
  905.         goto use_me;
  906.         }
  907.         if (!tin.tin->cursed)
  908.         pline("This makes you feel like %s!",
  909.               Hallucination ? "Swee'pea" : "Popeye");
  910.         lesshungry(600);
  911.         gainstr(tin.tin, 0);
  912.     }
  913.     tin.tin->dknown = tin.tin->known = TRUE;
  914. use_me:
  915.     if (carried(tin.tin)) useup(tin.tin);
  916.     else useupf(tin.tin);
  917.     tin.tin = (struct obj *) 0;
  918.     return(0);
  919. }
  920.  
  921. static void
  922. start_tin(otmp)        /* called when starting to open a tin */
  923.     register struct obj *otmp;
  924. {
  925.     register int tmp;
  926.  
  927. #ifdef POLYSELF
  928.     if (metallivorous(uasmon)) {
  929.         You("bite right into the metal tin....");
  930.         tmp = 1;
  931.     } else
  932. #endif
  933.     if (otmp->blessed) {
  934.         pline("The tin opens like magic!");
  935.         tmp = 1;
  936.     } else if(uwep) {
  937.         switch(uwep->otyp) {
  938.         case TIN_OPENER:
  939.             tmp = 1;
  940.             break;
  941.         case DAGGER:
  942.         case ELVEN_DAGGER:
  943.         case ORCISH_DAGGER:
  944.         case ATHAME:
  945.         case CRYSKNIFE:
  946.             tmp = 3;
  947.             break;
  948.         case PICK_AXE:
  949.         case AXE:
  950.             tmp = 6;
  951.             break;
  952.         default:
  953.             goto no_opener;
  954.         }
  955.         pline("Using your %s you try to open the tin.",
  956.             aobjnam(uwep, NULL));
  957.     } else {
  958. no_opener:
  959.         pline("It is not so easy to open this tin.");
  960.         if(Glib) {
  961.             pline("The tin slips out of your hands.");
  962.             if(otmp->quan > 1L) {
  963.                 register struct obj *obj;
  964.                 obj = splitobj(otmp, 1L);
  965.                 if(otmp == uwep) setuwep(obj);
  966.             }
  967.             if (carried(otmp)) dropx(otmp);
  968.             else stackobj(otmp);
  969.             return;
  970.         }
  971.         tmp = rn1(1 + 500/((int)(ACURR(A_DEX) + ACURRSTR)), 10);
  972.     }
  973.     tin.reqtime = tmp;
  974.     tin.usedtime = 0;
  975.     tin.tin = otmp;
  976.     set_occupation(opentin, "opening the tin", 0);
  977.     return;
  978. }
  979.  
  980. int
  981. Hear_again() {        /* called when waking up after fainting */
  982.     flags.soundok = 1;
  983.     return 0;
  984. }
  985.  
  986. static int
  987. #ifdef POLYSELF
  988. rottenfood(obj)
  989. struct obj *obj;
  990. #else
  991. rottenfood()
  992. #endif
  993. {        /* called on the "first bite" of rotten food */
  994. #ifdef POLYSELF
  995.     pline("Blecch!  Rotten %s!", foodword(obj));
  996. #else
  997.     pline("Blecch!  Rotten food!");
  998. #endif
  999.     if(!rn2(4)) {
  1000.         if (Hallucination) You("feel rather trippy.");
  1001.         else You("feel rather %s.", body_part(LIGHT_HEADED));
  1002.         make_confused(HConfusion + d(2,4),FALSE);
  1003.     } else if(!rn2(4) && !Blind) {
  1004.         pline("Everything suddenly goes dark.");
  1005.         make_blinded((long)d(2,10),FALSE);
  1006.     } else if(!rn2(3)) {
  1007.         if(Blind)
  1008.           pline("The world spins and you slap against the floor.");
  1009.         else
  1010.           pline("The world spins and goes dark.");
  1011.         flags.soundok = 0;
  1012.         nomul(-rnd(10));
  1013.         nomovemsg = "You are conscious again.";
  1014.         afternmv = Hear_again;
  1015.         return(1);
  1016.     }
  1017.     return(0);
  1018. }
  1019.  
  1020. static int
  1021. eatcorpse(otmp)        /* called when a corpse is selected as food */
  1022.     register struct obj *otmp;
  1023. {
  1024.     register const char *cname = mons[otmp->corpsenm].mname;
  1025.     register int tp, rotted = 0;
  1026.  
  1027.     tp = 0;
  1028.  
  1029.     if(otmp->corpsenm != PM_LIZARD) {
  1030. #ifndef LINT    /* problem if more than 320K moves before try to eat */
  1031.         rotted = (monstermoves - otmp->age)/((long)(10 + rn2(20)));
  1032. #endif
  1033.  
  1034.         if(otmp->cursed) rotted += 2;
  1035.         else if (otmp->blessed) rotted -= 2;
  1036.     }
  1037.  
  1038.     if(otmp->corpsenm != PM_ACID_BLOB && (rotted > 5)) {
  1039.         pline("Ulch - that %s was tainted!",
  1040.               mons[otmp->corpsenm].mlet == S_FUNGUS ? "fungoid vegetation" :
  1041.               is_meaty(&mons[otmp->corpsenm]) ? "meat" : "protoplasm");
  1042. #ifdef POLYSELF
  1043.         if (u.usym == S_FUNGUS)
  1044.             pline("It doesn't seem at all sickening, though...");
  1045.         else {
  1046. #endif
  1047.             make_sick((long) rn1(10, 10),FALSE);
  1048.             Sprintf(corpsename, "rotted %s corpse", cname);
  1049.             u.usick_cause = (const char *)corpsename;
  1050.             flags.botl = 1;
  1051. #ifdef POLYSELF
  1052.         }
  1053. #endif
  1054.         if (carried(otmp)) useup(otmp);
  1055.         else useupf(otmp);
  1056.         return(1);
  1057.     } else if(acidic(&mons[otmp->corpsenm])
  1058. #ifdef POLYSELF
  1059.           && !resists_acid(uasmon)
  1060. #endif
  1061.          ) {
  1062.         tp++;
  1063.         You("have a very bad case of stomach acid.");
  1064.         losehp(rnd(15), "acidic corpse", KILLED_BY_AN);
  1065.     } else if(poisonous(&mons[otmp->corpsenm]) && rn2(5)) {
  1066.         tp++;
  1067.         pline("Ecch - that must have been poisonous!");
  1068.         if(!Poison_resistance) {
  1069.             losestr(rnd(4));
  1070.             losehp(rnd(15), "poisonous corpse", KILLED_BY_AN);
  1071.         } else    You("seem unaffected by the poison.");
  1072.     /* now any corpse left too long will make you mildly ill */
  1073.     } else if(((rotted > 5) || ((rotted > 3) && rn2(5)))
  1074. #ifdef POLYSELF
  1075.         && u.usym != S_FUNGUS
  1076. #endif
  1077.                             ){
  1078.         tp++;
  1079.         You("feel%s sick.", (Sick) ? " very" : "");
  1080.         losehp(rnd(8), "cadaver", KILLED_BY_AN);
  1081.     }
  1082.     if(!tp && otmp->corpsenm != PM_LIZARD && (otmp->orotten || !rn2(7))) {
  1083. #ifdef POLYSELF
  1084.         if(rottenfood(otmp)) {
  1085. #else
  1086.         if(rottenfood()) {
  1087. #endif
  1088.         otmp->orotten = TRUE;
  1089.         (void)touchfood(otmp);
  1090.         return(1);
  1091.         }
  1092.         otmp->oeaten >>= 2;
  1093.     } else {
  1094. #ifdef POLYSELF
  1095.         pline("This %s corpse %s!", cname,
  1096.         (carnivorous(uasmon) && !herbivorous(uasmon))
  1097.         ? "is delicious" : "tastes terrible");
  1098. #else
  1099.         pline("This %s corpse tastes terrible!", cname);
  1100. #endif
  1101.     }
  1102.  
  1103.     /* delay is weight dependent */
  1104.     victual.reqtime = 3 + (mons[otmp->corpsenm].cwt >> 6);
  1105.     return(0);
  1106. }
  1107.  
  1108. static void
  1109. start_eating(otmp)        /* called as you start to eat */
  1110.     register struct obj *otmp;
  1111. {
  1112. #ifdef DEBUG
  1113.     debugpline("start_eating: %lx (victual = %lx)", otmp, victual.piece);
  1114.     debugpline("reqtime = %d", victual.reqtime);
  1115.     debugpline("(original reqtime = %d)", objects[otmp->otyp].oc_delay);
  1116.     debugpline("nmod = %d", victual.nmod);
  1117.     debugpline("oeaten = %d", otmp->oeaten);
  1118. #endif
  1119.     victual.fullwarn = victual.doreset = FALSE;
  1120.     victual.eating = TRUE;
  1121.  
  1122.     if (otmp->otyp == CORPSE) {
  1123.         cprefx(victual.piece->corpsenm);
  1124.         if (!victual.piece && victual.eating) do_reset_eat();
  1125.         if (victual.eating == FALSE) return; /* died and lifesaved */
  1126.     }
  1127.  
  1128.     if (bite()) return;
  1129.  
  1130.     if(++victual.usedtime >= victual.reqtime) {
  1131.         /* print "finish eating" message if they just resumed -dlc */
  1132.         done_eating(victual.reqtime > 1 ? TRUE : FALSE);
  1133.         return;
  1134.     }
  1135.  
  1136.     Sprintf(msgbuf, "eating %s", the(singular(otmp, xname)));
  1137.     set_occupation(eatfood, msgbuf, 0);
  1138. }
  1139.  
  1140.  
  1141. static void
  1142. fprefx(otmp)        /* called on "first bite" of (non-corpse) food */
  1143.  
  1144.     register struct obj *otmp;
  1145. {
  1146.     switch(otmp->otyp) {
  1147.  
  1148.         case FOOD_RATION:
  1149.         if(u.uhunger <= 200)
  1150.             if (Hallucination) pline("Oh wow, like, superior, man!");
  1151.             else           pline("That food really hit the spot!");
  1152.         else if(u.uhunger <= 700) pline("That satiated your stomach!");
  1153.         break;
  1154.         case TRIPE_RATION:
  1155. #ifdef POLYSELF
  1156.         if (carnivorous(uasmon) && !humanoid(uasmon))
  1157.             pline("That tripe ration was surprisingly good!");
  1158.         else {
  1159. #endif
  1160.             pline("Yak - dog food!");
  1161.             more_experienced(1,0);
  1162.             flags.botl = 1;
  1163. #ifdef POLYSELF
  1164.         }
  1165. #endif
  1166.         if(rn2(2)
  1167. #ifdef POLYSELF
  1168.             && (!carnivorous(uasmon) || humanoid(uasmon))
  1169. #endif
  1170.                         ) {
  1171.             make_vomiting((long)rn1(victual.reqtime, 14), FALSE);
  1172.         }
  1173.         break;
  1174. #ifdef POLYSELF
  1175.         case CLOVE_OF_GARLIC:
  1176.         if (is_undead(uasmon)) {
  1177.             make_vomiting((long)rn1(victual.reqtime, 5), FALSE);
  1178.             break;
  1179.         }
  1180.         /* Fall through otherwise */
  1181. #endif
  1182.         default:
  1183. #ifdef TUTTI_FRUTTI
  1184.         if (otmp->otyp==SLIME_MOLD && !otmp->cursed
  1185.             && otmp->spe == current_fruit)
  1186.             pline("My, that was a yummy %s!", singular(otmp, xname));
  1187.         else
  1188. #endif
  1189. #ifdef UNIX
  1190.         if (otmp->otyp == APPLE || otmp->otyp == PEAR) {
  1191.             if (!Hallucination) pline("Core dumped.");
  1192.             else {
  1193. /* This is based on an old Usenet joke, a fake a.out manual page */
  1194.             int x = rnd(100);
  1195.             if (x <= 75)
  1196.                 pline("Segmentation fault -- core dumped.");
  1197.             else if (x <= 99)
  1198.                 pline("Bus error -- core dumped.");
  1199.             else pline("Yo' mama -- core dumped.");
  1200.             }
  1201.         } else
  1202. #endif
  1203.             pline("This %s is %s!", singular(otmp, xname),
  1204.               otmp->cursed ? (Hallucination ? "grody" : "terrible"):
  1205.               Hallucination ? "gnarly" :
  1206.             (otmp->otyp==CRAM_RATION ? "bland" : "delicious"));
  1207.         break;
  1208.     }
  1209. }
  1210.  
  1211. #ifdef POLYSELF
  1212. static void
  1213. eatring(otmp)
  1214. struct obj *otmp;
  1215. {
  1216.     int typ = otmp->otyp;
  1217.     int oldprop;
  1218.  
  1219.     /* Note: rings are not so common that this is unbalancing.  (How */
  1220.     /* often do you even _find_ 3 rings of polymorph in a game? */
  1221.     oldprop = !!(u.uprops[objects[typ].oc_oprop].p_flgs);
  1222.     otmp->known = otmp->dknown = 1; /* by taste */
  1223.     if (!rn2(3)) switch (otmp->otyp) {
  1224.         case RIN_AGGRAVATE_MONSTER:
  1225.         case RIN_WARNING:
  1226.         case RIN_POISON_RESISTANCE:
  1227.         case RIN_FIRE_RESISTANCE:
  1228.         case RIN_COLD_RESISTANCE:
  1229.         case RIN_SHOCK_RESISTANCE:
  1230.         case RIN_TELEPORTATION:
  1231.         case RIN_TELEPORT_CONTROL:
  1232.         case RIN_SEE_INVISIBLE:
  1233.         case RIN_PROTECTION_FROM_SHAPE_CHAN:
  1234.         case RIN_SEARCHING:
  1235.         case RIN_STEALTH:
  1236.         case RIN_INVISIBILITY:
  1237.         case RIN_CONFLICT:
  1238.         case RIN_POLYMORPH:
  1239.         case RIN_POLYMORPH_CONTROL:
  1240.         case RIN_REGENERATION: /* Probably stupid. */
  1241.         case RIN_HUNGER: /* Stupid. */
  1242.         case RIN_LEVITATION: /* Stupid. */
  1243.         if (!(u.uprops[objects[typ].oc_oprop].p_flgs & FROMOUTSIDE))
  1244.             pline("Magic spreads through your body as you digest the ring.");
  1245.         u.uprops[objects[typ].oc_oprop].p_flgs |= FROMOUTSIDE;
  1246.         if (typ == RIN_SEE_INVISIBLE) {
  1247.             set_mimic_blocking();
  1248.             see_monsters();
  1249.             if (Invis && !oldprop
  1250. #ifdef POLYSELF
  1251.                 && !perceives(uasmon)
  1252. #endif
  1253.                             && !Blind) {
  1254.             newsym(u.ux,u.uy);
  1255.             pline("Suddenly you can see yourself.");
  1256.             makeknown(typ);
  1257.             }
  1258.         } else if (typ == RIN_INVISIBILITY) {
  1259.             if (!oldprop && !See_invisible && !Blind) {
  1260.             newsym(u.ux,u.uy);
  1261.             Your("body takes on a %s transparency...",
  1262.                 Hallucination ? "normal" : "strange");
  1263.             makeknown(typ);
  1264.             }
  1265.         } else if (typ == RIN_PROTECTION_FROM_SHAPE_CHAN)
  1266.             rescham();
  1267.         else if (typ == RIN_LEVITATION) {
  1268.             if (!Levitation) {
  1269.             float_up();
  1270.             makeknown(typ);
  1271.             }
  1272.         }
  1273.         break;
  1274.         case RIN_ADORNMENT:
  1275.         if (adjattrib(A_CHA, otmp->spe, -1))
  1276.             makeknown(typ);
  1277.         break;
  1278.         case RIN_GAIN_STRENGTH:
  1279.         case RIN_INCREASE_DAMAGE: /* Any better ideas? */
  1280.         if (adjattrib(A_STR, otmp->spe, -1))
  1281.             makeknown(typ);
  1282.         break;
  1283.         case RIN_PROTECTION:
  1284.         Protection |= FROMOUTSIDE;
  1285.         u.ublessed += otmp->spe;
  1286.         flags.botl = 1;
  1287.         break;
  1288.     }
  1289. }
  1290.  
  1291. static void
  1292. eatspecial() /* called after eating non-food */
  1293. {
  1294.     register struct obj *otmp = victual.piece;
  1295.  
  1296.     lesshungry(victual.nmod);
  1297.     victual.piece = (struct obj *)0;
  1298.     victual.eating = 0;
  1299.     if (otmp->oclass == GOLD_CLASS) {
  1300.         dealloc_obj(otmp);
  1301.         return;
  1302.     }
  1303.     if (otmp->oclass == POTION_CLASS) {
  1304.         otmp->quan++; /* dopotion() does a useup() */
  1305.         (void)dopotion(otmp);
  1306.     }
  1307.     if (otmp->oclass == RING_CLASS)
  1308.         eatring(otmp);
  1309.     if (otmp == uball) unpunish();
  1310.     if (otmp == uchain) unpunish(); /* but no useup() */
  1311.     else if (carried(otmp)) useup(otmp);
  1312.     else useupf(otmp);
  1313. }
  1314.  
  1315. /* NOTE: the order of these words exactly corresponds to the
  1316.    order of oc_material values #define'd in objclass.h. */
  1317. static const char *foodwords[] = {
  1318.     "meal", "liquid", "wax", "food", "meat",
  1319.     "paper", "cloth", "leather", "wood", "bone", "scale",
  1320.     "metal", "metal", "metal", "silver", "gold", "platinum", "mithril",
  1321.     "plastic", "glass", "rich food", "stone"
  1322. };
  1323.  
  1324. static const char *
  1325. foodword(otmp)
  1326. register struct obj *otmp;
  1327. {
  1328.     if (otmp->oclass == FOOD_CLASS) return "food";
  1329.     if (otmp->oclass == GEM_CLASS &&
  1330.         objects[otmp->otyp].oc_material == GLASS &&
  1331.         otmp->dknown)
  1332.         makeknown(otmp->otyp);
  1333.     return foodwords[objects[otmp->otyp].oc_material];
  1334. }
  1335. #endif
  1336.  
  1337. static void
  1338. fpostfx(otmp)        /* called after consuming (non-corpse) food */
  1339.  
  1340.     register struct obj *otmp;
  1341. {
  1342.     switch(otmp->otyp) {
  1343. #ifdef POLYSELF
  1344.         case SPRIG_OF_WOLFSBANE:
  1345.         if (u.ulycn != -1) {
  1346.             u.ulycn = -1;
  1347.             You("feel purified.");
  1348.             if(uasmon == &mons[u.ulycn] && !Polymorph_control)
  1349.             rehumanize();
  1350.         }
  1351.         break;
  1352. #endif
  1353.         case CARROT:
  1354.         make_blinded(0L,TRUE);
  1355.         break;
  1356.         case FORTUNE_COOKIE:
  1357.         outrumor(bcsign(otmp), TRUE);
  1358.         break;
  1359.         case LUMP_OF_ROYAL_JELLY:
  1360.         /* This stuff seems to be VERY healthy! */
  1361.         gainstr(otmp, 1);
  1362.         u.uhp += (otmp->cursed) ? -rnd(20) : rnd(20);
  1363.         if(u.uhp > u.uhpmax) {
  1364.             if(!rn2(17)) u.uhpmax++;
  1365.             u.uhp = u.uhpmax;
  1366.         } else if(u.uhp <= 0) {
  1367.             killer_format = KILLED_BY_AN;
  1368.             killer = "rotten lump of royal jelly";
  1369.             done(POISONING);
  1370.         }
  1371.         if(!otmp->cursed) heal_legs();
  1372.         break;
  1373.         case EGG:
  1374.         if(otmp->corpsenm == PM_COCKATRICE) {
  1375. #ifdef POLYSELF
  1376.             if(!resists_ston(uasmon))
  1377.             if(!poly_when_stoned(uasmon) ||
  1378.                !polymon(PM_STONE_GOLEM))
  1379.             {
  1380. #endif
  1381.             if (!Stoned) Stoned = 5;
  1382.             killer_format = KILLED_BY_AN;
  1383.             killer = "cockatrice egg";
  1384. #ifdef POLYSELF
  1385.             }
  1386. #endif
  1387.         }
  1388.         break;
  1389.     }
  1390.     return;
  1391. }
  1392.  
  1393. int
  1394. doeat()        /* generic "eat" command funtion (see cmd.c) */
  1395. {
  1396.     register struct obj *otmp;
  1397.     int basenutrit;            /* nutrition of full item */
  1398.  
  1399.     if (Strangled) {
  1400.         pline("If you can't breathe air, how can you consume solids?");
  1401.         return 0;
  1402.     }
  1403.     if (!(otmp = floorfood("eat", 0))) return 0;
  1404.     if (check_capacity(NULL)) return 0;
  1405. #ifdef POLYSELF
  1406.     /* We have to make non-foods take no time to eat, unless we want to
  1407.      * do ridiculous amounts of coding to deal with partly eaten plate
  1408.      * mails, players who polymorph back to human in the middle of their
  1409.      * metallic meal, etc....
  1410.      */
  1411.     if (!is_edible(otmp)) {
  1412.         You("cannot eat that!");
  1413.         return 0;
  1414.     }
  1415.     if (otmp->oclass != FOOD_CLASS) {
  1416.         victual.reqtime = 1;
  1417.         victual.piece = otmp;
  1418.         /* Don't split it, we don't need to if it's 1 move */
  1419.         victual.usedtime = 0;
  1420.         victual.canchoke = (u.uhs == SATIATED);
  1421.         /* Note: gold weighs 1 pt. for each 1000 pieces (see */
  1422.         /* pickup.c) so gold and non-gold is consistent. */
  1423.         if (otmp->oclass == GOLD_CLASS)
  1424.         basenutrit = ((otmp->quan > 200000L) ? 2000
  1425.             : (int)(otmp->quan/100L));
  1426.         else basenutrit = objects[otmp->otyp].oc_nutrition;
  1427.         victual.nmod = basenutrit;
  1428.         victual.eating = TRUE; /* needed for lesshungry() */
  1429.  
  1430.         if (otmp->cursed)
  1431.         (void) rottenfood(otmp);
  1432.  
  1433.         if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
  1434.         pline("Ecch - that must have been poisonous!");
  1435.         if(!Poison_resistance) {
  1436.             losestr(rnd(4));
  1437.             losehp(rnd(15), xname(otmp), KILLED_BY_AN);
  1438.         } else
  1439.             You("seem unaffected by the poison.");
  1440.         } else if (!otmp->cursed)
  1441.         pline("This %s is delicious!",
  1442.               otmp->oclass == GOLD_CLASS ? foodword(otmp) :
  1443.               singular(otmp, xname));
  1444.         eatspecial();
  1445.         return 1;
  1446.     }
  1447. #endif
  1448.  
  1449.     if(otmp == victual.piece) {
  1450.     /* If they weren't able to choke, they don't suddenly become able to
  1451.      * choke just because they were interrupted.  On the other hand, if
  1452.      * they were able to choke before, if they lost food it's possible
  1453.      * they shouldn't be able to choke now.
  1454.      */
  1455.         if (u.uhs != SATIATED) victual.canchoke = FALSE;
  1456.         if(!carried(victual.piece)) {
  1457.         if(victual.piece->quan > 1L)
  1458.             (void) splitobj(victual.piece, 1L);
  1459.         }
  1460.         You("resume your meal.");
  1461.         start_eating(victual.piece);
  1462.         return(1);
  1463.     }
  1464.  
  1465.     /* nothing in progress - so try to find something. */
  1466.     /* tins are a special case */
  1467.     if(otmp->otyp == TIN) {
  1468.         start_tin(otmp);
  1469.         return(1);
  1470.     }
  1471.  
  1472.     victual.piece = otmp = touchfood(otmp);
  1473.     victual.usedtime = 0;
  1474.  
  1475.     /* Now we need to calculate delay and nutritional info.
  1476.      * The base nutrition calculated here and in eatcorpse() accounts
  1477.      * for normal vs. rotten food.  The reqtime and nutrit values are
  1478.      * then adjusted in accordance with the amount of food left.
  1479.      */
  1480.     if(otmp->otyp == CORPSE) {
  1481.         if(eatcorpse(otmp)) return(1);
  1482.         /* else eatcorpse sets up reqtime and oeaten */
  1483.     } else {
  1484.         victual.reqtime = objects[otmp->otyp].oc_delay;
  1485.         if (otmp->otyp != FORTUNE_COOKIE &&
  1486.         (otmp->cursed ||
  1487.          (((monstermoves - otmp->age) > (int) otmp->blessed ? 50:30) &&
  1488.         (otmp->orotten || !rn2(7))))) {
  1489.  
  1490. #ifdef POLYSELF
  1491.         if(rottenfood(otmp)) {
  1492. #else
  1493.         if(rottenfood()) {
  1494. #endif
  1495.             otmp->orotten = TRUE;
  1496.             return(1);
  1497.         }
  1498.         otmp->oeaten >>= 1;
  1499.         } else fprefx(otmp);
  1500.     }
  1501.  
  1502.     /* re-calc the nutrition */
  1503.     if (otmp->otyp == CORPSE) basenutrit = mons[otmp->corpsenm].cnutrit;
  1504.     else basenutrit = objects[otmp->otyp].oc_nutrition;
  1505.  
  1506. #ifdef DEBUG
  1507.     debugpline("before rounddiv: victual.reqtime == %d", victual.reqtime);
  1508.     debugpline("oeaten == %d, basenutrit == %d", otmp->oeaten, basenutrit);
  1509. #endif
  1510.     victual.reqtime = (basenutrit == 0 ? 0 :
  1511.         rounddiv(victual.reqtime * (long)otmp->oeaten, basenutrit));
  1512. #ifdef DEBUG
  1513.     debugpline("after rounddiv: victual.reqtime == %d", victual.reqtime);
  1514. #endif
  1515.     /* calculate the modulo value (nutrit. units per round eating)
  1516.      * note: this isn't exact - you actually lose a little nutrition
  1517.      *     due to this method.
  1518.      * TODO: add in a "remainder" value to be given at the end of the
  1519.      *     meal.
  1520.      */
  1521.     if(victual.reqtime == 0)
  1522.         /* possible if most has been eaten before */
  1523.         victual.nmod = 0;
  1524.     else if (otmp->oeaten > victual.reqtime)
  1525.         victual.nmod = -(otmp->oeaten / victual.reqtime);
  1526.     else
  1527.         victual.nmod = victual.reqtime % otmp->oeaten;
  1528.     victual.canchoke = (u.uhs == SATIATED);
  1529.  
  1530.     start_eating(otmp);
  1531.     return(1);
  1532. }
  1533.  
  1534. /* Take a single bite from a piece of food, checking for choking and
  1535.  * modifying usedtime.  Returns 1 if they choked and survived, 0 otherwise.
  1536.  */
  1537. static int
  1538. bite()
  1539. {
  1540.     if(victual.canchoke && u.uhunger >= 2000) {
  1541.         choke(victual.piece);
  1542.         return 1;
  1543.     }
  1544.     if (victual.doreset) {
  1545.         do_reset_eat();
  1546.         return 0;
  1547.     }
  1548.     if(victual.nmod < 0) {
  1549.         lesshungry(-victual.nmod);
  1550.         victual.piece->oeaten -= -victual.nmod;
  1551.     } else if(victual.nmod > 0 && (victual.usedtime % victual.nmod)) {
  1552.         lesshungry(1);
  1553.         victual.piece->oeaten--;
  1554.     }
  1555.     recalc_wt();
  1556.     return 0;
  1557. }
  1558.  
  1559. #endif /* OVLB */
  1560. #ifdef OVL0
  1561.  
  1562. void
  1563. gethungry()    /* as time goes by - called by moveloop() and domove() */
  1564. {
  1565.     if (u.uinvulnerable) return;    /* you don't feel hungrier */
  1566.  
  1567.     if ((!u.usleep || !rn2(10))    /* slow metabolic rate while asleep */
  1568.         && (carnivorous(uasmon) || herbivorous(uasmon)))
  1569.         u.uhunger--;        /* ordinary food consumption */
  1570.  
  1571.     if (moves % 2) {    /* odd turns */
  1572.         /* Regeneration uses up food, unless due to an artifact */
  1573.         if ((HRegeneration & (~W_ART)) &&
  1574.         (HRegeneration != W_WEP || !uwep->oartifact)) u.uhunger--;
  1575.         if (near_capacity() > SLT_ENCUMBER) u.uhunger--;
  1576.     } else {        /* even turns */
  1577.         if (Hunger) u.uhunger--;
  1578.         /* Conflict uses up food too */
  1579.         if ((Conflict & (~W_ARTI))) u.uhunger--;
  1580.         /* +0 charged rings don't do anything, so don't affect hunger */
  1581.         switch (moves % 20) {    /* note: use even cases only */
  1582.          case  4: if (uleft &&
  1583.               (uleft->spe || !objects[uleft->otyp].oc_charged))
  1584.                 u.uhunger--;
  1585.             break;
  1586.          case  8: if (uamul) u.uhunger--;
  1587.             break;
  1588.          case 12: if (uright &&
  1589.               (uright->spe || !objects[uright->otyp].oc_charged))
  1590.                 u.uhunger--;
  1591.             break;
  1592.          case 16: if (u.uhave.amulet) u.uhunger--;
  1593.             break;
  1594.          default: break;
  1595.         }
  1596.     }
  1597.     newuhs(TRUE);
  1598. }
  1599.  
  1600. #endif /* OVL0 */
  1601. #ifdef OVLB
  1602.  
  1603. void
  1604. morehungry(num)    /* called after vomiting and after performing feats of magic */
  1605. register int num;
  1606. {
  1607.     u.uhunger -= num;
  1608.     newuhs(TRUE);
  1609. }
  1610.  
  1611.  
  1612. void
  1613. lesshungry(num)    /* called after eating (and after drinking fruit juice) */
  1614. register int num;
  1615. {
  1616. #ifdef DEBUG
  1617.     debugpline("lesshungry(%d)", num);
  1618. #endif
  1619.     u.uhunger += num;
  1620.     if(u.uhunger >= 2000) {
  1621.         if (!victual.eating || victual.canchoke)
  1622.         if (victual.eating) {
  1623.             choke(victual.piece);
  1624.             reset_eat();
  1625.         } else
  1626.         if (tin.tin)
  1627.             choke(tin.tin);
  1628.         else
  1629.             choke((struct obj *) 0);
  1630.         /* no reset_eat(); it was a non-food such as juice */
  1631.     } else {
  1632.         /* Have lesshungry() report when you're nearly full so all eating
  1633.          * warns when you're about to choke.
  1634.          */
  1635.         if (u.uhunger >= 1500) {
  1636.           if(!victual.eating || (victual.eating && !victual.fullwarn)) {
  1637.         pline("You're having a hard time getting all of it down.");
  1638.         nomovemsg = "You're finally finished.";
  1639.         if(!victual.eating)
  1640.             multi = -2;
  1641.         else {
  1642.             victual.fullwarn = TRUE;
  1643.             if (victual.canchoke &&
  1644.             /* a one-gulp food will not survive a stop */
  1645.                 objects[victual.piece->otyp].oc_delay > 1) {
  1646.             if(yn("Stop eating?") == 'y')
  1647.             {
  1648.                 reset_eat();
  1649.                 nomovemsg = NULL;
  1650.             }
  1651.             }
  1652.         }
  1653.           }
  1654.         }
  1655.     }
  1656.     newuhs(FALSE);
  1657. }
  1658.  
  1659. STATIC_PTR
  1660. int
  1661. unfaint() {
  1662.     (void) Hear_again();
  1663.     if(u.uhs > FAINTING)
  1664.         u.uhs = FAINTING;
  1665.     stop_occupation();
  1666.     flags.botl = 1;
  1667.     return 0;
  1668. }
  1669.  
  1670. #endif /* OVLB */
  1671. #ifdef OVL0
  1672.  
  1673. boolean
  1674. is_fainted() {
  1675.     return(u.uhs == FAINTED);
  1676. }
  1677.  
  1678. void
  1679. reset_faint() {    /* call when a faint must be prematurely terminated */
  1680.     if(is_fainted()) nomul(0);
  1681. }
  1682.  
  1683. #if 0
  1684. void
  1685. sync_hunger() {
  1686.  
  1687.     if(is_fainted()) {
  1688.  
  1689.         flags.soundok = 0;
  1690.         nomul(-10+(u.uhunger/10));
  1691.         nomovemsg = "You regain consciousness.";
  1692.         afternmv = unfaint;
  1693.     }
  1694. }
  1695. #endif
  1696.  
  1697. void
  1698. newuhs(incr)        /* compute and comment on your (new?) hunger status */
  1699.     boolean incr;
  1700. {
  1701.     register int newhs, h = u.uhunger;
  1702.  
  1703.     newhs = (h > 1000) ? SATIATED :
  1704.         (h > 150) ? NOT_HUNGRY :
  1705.         (h > 50) ? HUNGRY :
  1706.         (h > 0) ? WEAK : FAINTING;
  1707.  
  1708.     if(newhs == FAINTING) {
  1709.         if(is_fainted()) newhs = FAINTED;
  1710.         if(u.uhs <= WEAK || rn2(20-u.uhunger/10) >= 19) {
  1711.             if(!is_fainted() && multi >= 0 /* %% */) {
  1712.                 /* stop what you're doing, then faint */
  1713.                 stop_occupation();
  1714.                 You("faint from lack of food.");
  1715.                 flags.soundok = 0;
  1716.                 nomul(-10+(u.uhunger/10));
  1717.                 nomovemsg = "You regain consciousness.";
  1718.                 afternmv = unfaint;
  1719.                 newhs = FAINTED;
  1720.             }
  1721.         } else
  1722.         if(u.uhunger < -(int)(200 + 20*ACURR(A_CON))) {
  1723.             u.uhs = STARVED;
  1724.             flags.botl = 1;
  1725.             bot();
  1726.             You("die from starvation.");
  1727.             killer_format = KILLED_BY;
  1728.             killer = "starvation";
  1729.             done(STARVING);
  1730.             /* if we return, we lifesaved, and that calls newuhs */
  1731.             return;
  1732.         }
  1733.     }
  1734.  
  1735.     if(newhs != u.uhs) {
  1736.         if(newhs >= WEAK && u.uhs < WEAK)
  1737.             losestr(1);    /* this may kill you -- see below */
  1738.         else if(newhs < WEAK && u.uhs >= WEAK)
  1739.             losestr(-1);
  1740.         switch(newhs){
  1741.         case HUNGRY:
  1742.             if (Hallucination) {
  1743.                 pline((!incr) ?
  1744.                 "You now have a lesser case of the munchies." :
  1745.                 "You are getting the munchies.");
  1746.             } else
  1747.                 You((!incr) ? "only feel hungry now." :
  1748.                   (u.uhunger < 145) ? "feel hungry." :
  1749.                    "are beginning to feel hungry.");
  1750.             if (incr && occupation &&
  1751.                 (occupation != eatfood && occupation != opentin))
  1752.                 stop_occupation();
  1753.             break;
  1754.         case WEAK:
  1755.             if (Hallucination)
  1756.                 pline((!incr) ?
  1757.                   "You still have the munchies." :
  1758.       "The munchies are interfering with your motor capabilities.");
  1759.             else
  1760.                 You((!incr) ? "feel weak now." :
  1761.                   (u.uhunger < 45) ? "feel weak." :
  1762.                    "are beginning to feel weak.");
  1763.             if (incr && occupation &&
  1764.                 (occupation != eatfood && occupation != opentin))
  1765.                 stop_occupation();
  1766.             break;
  1767.         }
  1768.         u.uhs = newhs;
  1769.         flags.botl = 1;
  1770.         if(u.uhp < 1) {
  1771.             You("die from hunger and exhaustion.");
  1772.             killer_format = KILLED_BY;
  1773.             killer = "exhaustion";
  1774.             done(STARVING);
  1775.             return;
  1776.         }
  1777.     }
  1778. }
  1779.  
  1780. #endif /* OVL0 */
  1781. #ifdef OVLB
  1782.  
  1783. /* Returns an object representing food.  Object may be either on floor or
  1784.  * in inventory.
  1785.  */
  1786. struct obj *
  1787. floorfood(verb,corpseonly)    /* get food from floor or pack */
  1788.     const char *verb;
  1789.     boolean corpseonly;
  1790. {
  1791.     register struct obj *otmp;
  1792.     char qbuf[QBUFSZ];
  1793.     char c;
  1794. #ifdef POLYSELF
  1795.     struct obj *gold = g_at(u.ux, u.uy);
  1796.     boolean feeding = (!strcmp(verb, "eat"));
  1797.  
  1798.     if (feeding && gold && metallivorous(uasmon)) {
  1799.         if (gold->quan == 1L)
  1800.         Sprintf(qbuf, "There is 1 gold piece here; eat it?");
  1801.         else Sprintf(qbuf, "There are %ld gold pieces here; eat them?",
  1802.                                 gold->quan);
  1803.         if (yn(qbuf) == 'y') {
  1804.         /* tricky, because gold isn't a real object -dlc */
  1805.         freeobj(gold);
  1806.         return gold;
  1807.         }
  1808.     }
  1809. #endif
  1810.     /* Is there some food (probably a heavy corpse) here on the ground? */
  1811.     if (!(Levitation && !Is_airlevel(&u.uz)  && !Is_waterlevel(&u.uz))
  1812.         && !u.uswallow) {
  1813.         for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) {
  1814.         if(corpseonly ? otmp->otyp==CORPSE :
  1815. #ifdef POLYSELF
  1816.             feeding ? (otmp->oclass != GOLD_CLASS && is_edible(otmp)) :
  1817. #endif
  1818.                         otmp->oclass==FOOD_CLASS) {
  1819.             Sprintf(qbuf, "There %s %s here; %s %s?",
  1820.                 (otmp->quan == 1L) ? "is" : "are",
  1821.                 doname(otmp), verb,
  1822.                 (otmp->quan == 1L) ? "it" : "one");
  1823.             if((c = yn_function(qbuf,ynqchars,'n')) == 'y')
  1824.                 return(otmp);
  1825.             else if(c == 'q')
  1826.                 return((struct obj *) 0);
  1827.         }
  1828.         }
  1829.     }
  1830. #ifdef POLYSELF
  1831.     /* We cannot use ALL_CLASSES since that causes getobj() to skip its
  1832.      * "ugly checks" and we need to check for inedible items.
  1833.      */
  1834.     return getobj(feeding ? (const char *)allobj :
  1835.                 (const char *)comestibles, verb);
  1836. #else
  1837.     return getobj(comestibles, verb);
  1838. #endif
  1839. }
  1840.  
  1841. /* Side effects of vomiting */
  1842. /* added nomul (MRS) - it makes sense, you're too busy being sick! */
  1843. /* TO DO: regurgitate swallowed monsters when poly'd */
  1844. void
  1845. vomit() {        /* A good idea from David Neves */
  1846.     make_sick(0L,TRUE);
  1847.     nomul(-2);
  1848. }
  1849.  
  1850. int
  1851. eaten_stat(base, obj)
  1852. register int base;
  1853. register struct obj *obj;
  1854. {
  1855.     long uneaten_amt, full_amount;
  1856.  
  1857.     uneaten_amt = (long)obj->oeaten;
  1858.     full_amount = (obj->otyp == CORPSE) ? (long)mons[obj->corpsenm].cnutrit
  1859.                     : (long)objects[obj->otyp].oc_nutrition;
  1860.  
  1861.     base = (int)(full_amount ? (long)base * uneaten_amt / full_amount : 0L);
  1862.     return (base < 1) ? 1 : base;
  1863. }
  1864.  
  1865. #endif /* OVLB */
  1866.  
  1867. /*eat.c*/
  1868.